package com.sojson.util;

import static com.sojson.constant.ConstantByMap.EXCEL_PATH;
import static com.sojson.constant.ConstantByMap.IMG_PATH;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Random;
import java.util.UUID;

import javax.servlet.http.HttpServletRequest;

import org.springframework.core.io.ClassPathResource;
import org.springframework.util.DigestUtils;
import org.springframework.web.multipart.MultipartFile;

import com.sojson.constant.Constant;
import com.sojson.result.Result;
import com.sojson.util.file.FileUtil;
import com.sojson.util.file.bean.UploadBean;
import com.sojson.util.file.depot.FileDepotUtil;
import com.sojson.util.file.enums.EFileType;

import lombok.extern.slf4j.Slf4j;

@Slf4j
public class ToolsUtil {

    /** 工资模板文件基础路径 */
    public static final String SALARY_EXCEL_TEMPATE_PATH = EXCEL_PATH + "/salary/template.xlsx";
    /** 头像文件基础路径 */
    public static final String HEAD_IMG_PATH = IMG_PATH + "/head";
    /** 用户身份证基础路径 */
    public static final String ID_CARD = IMG_PATH + "/idCard";
    /** 验证码图片基础路径 */
    public static final String VERIFY_IMG = IMG_PATH + "/verifyImg";
    /** 企业资质照片文件基础路径 */
    public static final String BUSINESS_CERT_IMG_PATH = IMG_PATH + "/businessCert";
    /** 商品分类缩略图文件基础路径 */
    public static final String GOOD_CATE_THUMB = IMG_PATH + "/good/cateThumb";
    /** 商品缩略图文件基础路径 */
    public static final String GOOD_THUMB = IMG_PATH + "/good/thumb";
    /** 商品详情轮播图文件基础路径 */
    public static final String GOOD_IMAGES = IMG_PATH + "/good/images";
    /** 商品规格明细缩略图文件基础路径 */
    public static final String GOOD_SPECS_ATTR_THUMB = IMG_PATH + "/good/specsAttrThumb";
    /** 评论图片文件基础路径 */
    public static final String COMMENT_IMG_PATH = IMG_PATH + "/comment";
    /** 广告图片基础路径 */
    public static final String AD = IMG_PATH + "/ad";
    /** 许可证基础路径 */
    public static final String BUSINESS_LICENSE = IMG_PATH + "/uploadBusinessLicense";
    /** 图片类型白名单 */
    public static final String[] IMG_WHITE_LIST = new String[] {EFileType.JPG.getMimeType(),
        EFileType.JPEG.getMimeType(), EFileType.PNG.getMimeType(), EFileType.GIF.getMimeType()};
    /** 图片视频类型白名单 */
    public static final String[] IMG_VIDEO_WHITE_LIST =
        new String[] {EFileType.JPG.getMimeType(), EFileType.JPEG.getMimeType(), EFileType.PNG.getMimeType(),
            EFileType.GIF.getMimeType(), EFileType.MP4.getMimeType(), EFileType.MP4_2.getMimeType()};
    /** 图片大小 */
    public static final int IMG_SIZE = 100 * 1024 * 1024;
    /** resources路径 */
    public static final String RESOURCES_PATH = getResourcesPath();

    public static String getResourcesPath() {
        try {
            return new ClassPathResource("").getURL().getPath().substring(1);
        } catch (IOException e) {
            log.error(e.getMessage(), e);
        }
        return "";
    }

    /**
     * MD5加密
     *
     * @return String
     */
    public static String md5(String data) {
        return DigestUtils.md5DigestAsHex(data.getBytes());
    }

    /**
     * 获取随机数
     *
     * @param len 生成的长度
     * @return
     */
    public static String random(Integer len) {
        String seed = "ABCDEFGHJKLMNPQRSTUVWXYZ23456789abcdefghjkmnpqrstuvwxyz";
        String[] seedArr = seed.split("");
        // 生成数组结果
        char[] res = new char[len];

        Random random = new Random();
        int arrLen = seedArr.length;

        for (int i = 0; i < len; i++) {
            res[i] = seedArr[random.nextInt(arrLen)].charAt(0);
        }

        return new String(res);
    }

    /**
     * 获取客户端IP
     *
     * @param request
     * @return
     */
    public static String getIp(HttpServletRequest request) {
        String ip = request.getHeader("X-Forwarded-For");
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("WL-Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("HTTP_CLIENT_IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("HTTP_X_FORWARDED_FOR");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getRemoteAddr();
        }

        return ip;

    }

    /**
     * 上传
     *
     * @param file 上传的文件
     * @param path 存储路径
     * @param mimeTypeWhiteList 限制的文件mime
     * @param size 限制的文件大小 KB
     * @return
     * @throws Exception
     */
    public static Result<String> upload(MultipartFile file, String path, String[] mimeTypeWhiteList, double size)
        throws Exception {
        if (StringUtil.isBlankObject(mimeTypeWhiteList) || StringUtil.isBlankObject(file) || file.isEmpty()) {
            return Result.fail("文件不能为空");
        }

        // 文件后缀
        String suffix = null;
        EFileType fileType = FileUtil.getFileType(file);
        if (StringUtil.isNotBlankObject(fileType)) {
            suffix = fileType.getNameD();
        } else {
            // 文件名
            String fileName = file.getOriginalFilename();
            int lastIndexOf = fileName.lastIndexOf(".");
            suffix = lastIndexOf > -1 ? fileName.substring(lastIndexOf) : Constant.GENERATE_IMG.getNameD();
        }
        // 文件大小
        int fileSize = (int)file.getSize();
        // 验证大小
        if (size < fileSize) {
            return Result.fail("文件过大，最大允许上传" + String.format("%.2f", size / 1024 / 1024) + "M");
        }

        // 验证mime,文件类型
        boolean mimeRes = mimeTypeCheck(file, mimeTypeWhiteList);

        if (mimeRes == false) {
            return Result.fail("文件类型不允许");
        }

        UploadBean upload = FileUtil.upload(file.getBytes(), path, suffix);

        try {
            boolean uploadThisLocal = FileDepotUtil.uploadThisLocal(upload.getObjectName());
            if (!uploadThisLocal) {
                FileDepotUtil.deleteFileThisLocalByUrl(upload.getObjectName());
                return Result.fail("添加图片关联关系失败！");
            }
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            FileDepotUtil.deleteFileThisLocalByUrl(upload.getObjectName());
            return Result.fail("添加图片关联关系失败，" + e.getMessage());
        }
        return Result.success("上传成功", upload.getObjectName());
    }

    /**
     * 上传
     *
     * @param file 上传的文件
     * @param path 存储路径
     * @param mimeTypeWhiteList 限制的文件mime
     * @param size 限制的文件大小 KB
     * @return
     * @throws Exception
     */
    public static Result<List<String>> upload(MultipartFile[] files, String path, String[] mimeTypeWhiteList,
        double size) throws Exception {
        int length = files.length;
        if (StringUtil.isBlankObject(mimeTypeWhiteList) || StringUtil.isBlankObject(files) || length < 1) {
            return Result.fail("文件不能为空");
        }

        for (int i = 0; i < length; i++) {
            MultipartFile file = files[i];
            String fileName = file.getOriginalFilename();
            int fileSize = (int)file.getSize();
            // 验证大小
            if (size < fileSize) {
                return Result.fail(fileName + "文件过大，最大允许上传" + String.format("%.2f", size / 1024 / 1024) + "M");
            }

            // 验证mime,文件类型
            boolean mimeRes = mimeTypeCheck(file, mimeTypeWhiteList);

            if (mimeRes == false) {
                return Result.fail(fileName + "文件类型不允许");
            }
        }

        List<String> arrayList = new ArrayList<>();
        for (int i = 0; i < length; i++) {
            MultipartFile file = files[i];

            // 文件后缀
            String suffix = null;
            EFileType fileType = FileUtil.getFileType(file);
            if (StringUtil.isNotBlankObject(fileType)) {
                suffix = fileType.getNameD();
            } else {
                // 文件名
                String fileName = file.getOriginalFilename();
                int lastIndexOf = fileName.lastIndexOf(".");
                suffix = lastIndexOf > -1 ? fileName.substring(lastIndexOf) : Constant.GENERATE_IMG.getNameD();
            }

            try {
                UploadBean upload = FileUtil.upload(file.getBytes(), path, suffix);
                arrayList.add(upload.getObjectName());

                boolean uploadThisLocal = FileDepotUtil.uploadThisLocal(upload.getObjectName());
                if (!uploadThisLocal) {
                    FileDepotUtil.deleteFileThisLocalByUrl(arrayList);
                    return Result.fail("添加图片关联关系失败！");
                }
            } catch (Exception e) {
                FileDepotUtil.deleteFileThisLocalByUrl(arrayList);
                return Result.fail("添加图片关联关系失败，" + e.getMessage());
            }
        }
        return Result.success("上传成功", arrayList);
    }

    /**
     * MIMETYPE校验
     *  String[] mimeTypeWhiteList = {"image/jpeg","image/gif","image/png"};
     * @return
     */

    public static boolean mimeTypeCheck(MultipartFile uploadFile, String[] mimeTypeWhiteList) {
        if (uploadFile.isEmpty()) {
            return false;
        }
        // MultipartFile to File
        String mimeType = uploadFile.getContentType();
        // 白名单匹配
        boolean anyMatch = Arrays.stream(mimeTypeWhiteList).anyMatch(x -> x.equalsIgnoreCase(mimeType));
        return anyMatch;
    }

    /**
     * 生成随机字符串的工具类 uuid
     */
    public static String getUUID() {
        return UUID.randomUUID().toString().replace("-", "");
    }

}